package com.novacloud.fresh.authentication.jdbc;

import com.novacloud.fresh.model.login.DUser;
import com.novacloud.fresh.model.login.Users;
import com.novacloud.fresh.service.login.DUserService;
import com.novacloud.fresh.service.login.UserService;
import com.novacloud.fresh.util.ConstantModel;
import org.jasig.cas.adaptors.jdbc.AbstractJdbcUsernamePasswordAuthenticationHandler;
import org.jasig.cas.authentication.AccountDisabledException;
import org.jasig.cas.authentication.PreventedException;
import org.jasig.cas.authentication.principal.Principal;
import org.jasig.cas.authentication.principal.SimplePrincipal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;

import javax.security.auth.login.FailedLoginException;
import java.security.GeneralSecurityException;
import java.util.HashMap;
import java.util.Map;

/**
 * @param
 * @author <a href="mailto:huzhanjun@novacloud.com">huzj</a>
 * @version : 1.0
 * @date 2015-12-15 12:26
 */
public class AuthenticationHandler extends AbstractJdbcUsernamePasswordAuthenticationHandler {

    @Autowired
    private UserService userService;
    @Autowired
    private DUserService dUserService;

    /**
     * @param username
     * @param password
     * @return
     * @throws GeneralSecurityException
     * @throws PreventedException
     */
    @Override
    protected Principal authenticateUsernamePasswordInternal(String username, String password) throws GeneralSecurityException, PreventedException {

        final String encryptedPassword = this.getPasswordEncoder().encode(password);
        Map<String, Object> attributes = new HashMap<String, Object>();
        try {
            final Users user = userService.getByUserName(username);
            final String dbPassword = user.getPassword();
            if (!dbPassword.equals(encryptedPassword)) {
                throw new FailedLoginException("Password does not match value on record.");
            }
            // 验证是否被认证
            DUser dUser = dUserService.selectByPrimaryKey(user.getUserid());
            if (dUser == null || dUser.getIsusing() == null || !dUser.getIsusing().equals(ConstantModel.STATE_Y)) {
                throw new AccountDisabledException(user.getUsername() + "not been approved");
            }
            attributes.put("userName", user.getUsername());
            return new SimplePrincipal(user.getUserid(), attributes);
        } catch (final IncorrectResultSizeDataAccessException e) {
            if (e.getActualSize() <= 0) {
                throw new FailedLoginException(username + " not found with SQL query");
            } else {
                throw new FailedLoginException("Multiple records found for " + username);
            }
        } catch (final DataAccessException e) {
            throw new PreventedException("SQL exception while executing query for " + username, e);
        }
    }
}
